+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace SuperPolarity
+{
+ class Actor
+ {
+ protected SuperPolarity game;
+
+ public List<Actor> Children;
+
+ // Graphics / In-Game
+ protected Texture2D Texture;
+ protected Vector2 Origin;
+ public bool Active;
+ public Rectangle Box;
+ public Vector4 BoxDimensions;
+ protected Texture2D BoxTexture;
+
+ // Physical Properties
+ public Vector2 Position;
+ protected Vector2 Velocity;
+ protected Vector2 Acceleration;
+ public float Angle;
+
+ // Constraints / Behavior
+ public float MaxVelocity;
+ protected float AccelerationRate;
+ public int HP;
+ protected bool Immortal;
+ public bool Dying;
+ public int Value;
+ protected Color Color;
+
+ public Actor Parent;
+
+ public int Width
+ {
+ get { return Texture.Width; }
+ }
+
+ public int Height
+ {
+ get { return Texture.Height; }
+ }
+
+ public Actor(SuperPolarity newGame)
+ {
+ game = newGame;
+ BoxDimensions.X = 20;
+ BoxDimensions.Y = 20;
+ BoxDimensions.W = 15;
+ BoxDimensions.Z = 15;
+ }
+
+ public virtual void Initialize(Texture2D texture, Vector2 position)
+ {
+ Texture = texture;
+ Position = position;
+ Active = true;
+
+ Children = new List<Actor>();
+
+ Origin = new Vector2(Texture.Width / 2, Texture.Height / 2);
+ Velocity = new Vector2(0, 0);
+ Acceleration = new Vector2(0, 0);
+
+ MaxVelocity = 5;
+ AccelerationRate = 10;
+
+ HP = 1;
+ Immortal = false;
+
+ Dying = false;
+ Value = 1;
+
+ InitBox();
+ BoxTexture = new Texture2D(game.GraphicsDevice, 1, 1);
+ BoxTexture.SetData(new Color[] { Color.White });
+
+ Color = Color.White;
+ }
+
+ protected void InitBox()
+ {
+ Box = new Rectangle((int)(Position.X - BoxDimensions.X), (int)(Position.Y - BoxDimensions.X), (int)(BoxDimensions.X + BoxDimensions.X + BoxDimensions.W), (int)(BoxDimensions.Y + BoxDimensions.Y + BoxDimensions.Z));
+ }
+
+ public void AutoDeccelerate(GameTime gameTime)
+ {
+ if (Acceleration.X == 0 && Velocity.X > 0)
+ {
+ if (AccelerationRate * gameTime.ElapsedGameTime.TotalSeconds > Velocity.X)
+ {
+ Velocity.X = 0;
+ Acceleration.X = 0;
+ }
+ else
+ {
+ Acceleration.X = -AccelerationRate;
+ }
+ }
+
+ if (Acceleration.X == 0 && Velocity.X < 0)
+ {
+ if (-AccelerationRate * gameTime.ElapsedGameTime.TotalSeconds < Velocity.X)
+ {
+ Velocity.X = 0;
+ Acceleration.X = 0;
+ }
+ else
+ {
+ Acceleration.X = AccelerationRate;
+ }
+ }
+
+ if (Acceleration.Y == 0 && Velocity.Y > 0)
+ {
+ if (AccelerationRate * gameTime.ElapsedGameTime.TotalSeconds > Velocity.Y)
+ {
+ Velocity.Y = 0;
+ Acceleration.Y = 0;
+ }
+ else
+ {
+ Acceleration.Y = -AccelerationRate;
+ }
+ }
+
+ if (Acceleration.Y == 0 && Velocity.Y < 0)
+ {
+ if (-AccelerationRate * gameTime.ElapsedGameTime.TotalSeconds < Velocity.Y)
+ {
+ Velocity.Y = 0;
+ Acceleration.Y = 0;
+ }
+ else
+ {
+ Acceleration.Y = AccelerationRate;
+ }
+ }
+ }
+
+ public virtual void Update(GameTime gameTime)
+ {
+ Move(gameTime);
+ ChangeAngle();
+ CheckOutliers();
+ UpdateBox();
+ }
+
+ protected virtual void UpdateBox()
+ {
+ Box.X = (int)(Position.X - BoxDimensions.X);
+ Box.Y = (int)(Position.Y - BoxDimensions.Y);
+ }
+
+ public virtual void Move(GameTime gameTime)
+ {
+ AutoDeccelerate(gameTime);
+
+ var maxVelocity = MaxVelocity;
+
+ Velocity.X = Velocity.X + Acceleration.X * (float)gameTime.ElapsedGameTime.TotalSeconds;
+ Velocity.Y = Velocity.Y + Acceleration.Y * (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+ if (Velocity.X > MaxVelocity)
+ {
+ Velocity.X = MaxVelocity;
+ }
+
+ if (Velocity.X < -MaxVelocity)
+ {
+ Velocity.X = -MaxVelocity;
+ }
+
+ if (Velocity.Y > MaxVelocity)
+ {
+ Velocity.Y = MaxVelocity;
+ }
+
+ if (Velocity.Y < -MaxVelocity)
+ {
+ Velocity.Y = -MaxVelocity;
+ }
+
+ Position.X = Position.X + Velocity.X;
+ Position.Y = Position.Y + Velocity.Y;
+ }
+
+ public void ChangeAngle()
+ {
+ if (Math.Abs(Velocity.Y) <= 0.1 && Math.Abs(Velocity.X) <= 0.1)
+ {
+ return;
+ }
+ Angle = (float)Math.Atan2(Velocity.Y, Velocity.X);
+ }
+
+ public virtual void Draw(SpriteBatch spriteBatch)
+ {
+ Actor child = null;
+
+ // TODO: Check what's up with the null children.
+ if (Children == null)
+ {
+ return;
+ }
+ for (var i = Children.Count - 1; i >= 0; i--)
+ {
+ child = Children[i];
+ child.Draw(spriteBatch);
+ }
+
+ spriteBatch.Draw(Texture, Position, null, Color, Angle, Origin, 1f, SpriteEffects.None, 0f);
+ //spriteBatch.Draw(BoxTexture, Box, new Color(255, 0, 255, 25));
+ }
+
+ void CheckOutliers()
+ {
+ for (var i = Children.Count; i > 0; i--)
+ {
+ var actor = Children[i - 1];
+ if (actor.Position.X < -SuperPolarity.OutlierBounds || actor.Position.Y < -SuperPolarity.OutlierBounds ||
+ actor.Position.X > game.GraphicsDevice.Viewport.Width + SuperPolarity.OutlierBounds ||
+ actor.Position.Y > game.GraphicsDevice.Viewport.Height + SuperPolarity.OutlierBounds)
+ {
+ Children.Remove(actor);
+ }
+ }
+ }
+
+ public virtual void Collide(Actor other, Rectangle collision)
+ {
+ }
+
+ public void TakeDamage(int amount)
+ {
+ if (!Immortal)
+ {
+ HP = HP - amount;
+ if (HP < 0)
+ {
+ Die();
+ }
+ }
+ }
+
+ protected virtual void Die()
+ {
+ Dying = true;
+ }
+
+ public virtual void CleanUp()
+ {
+ Texture = null;
+ BoxTexture = null;
+ Children = null;
+ Texture = null;
+ }
+ }
+}